package cn.xenosp.server.common.tomcat;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import java.util.Map;

/**
 * 项目名： service-web
 * 包路径： cn.xenosp.server.common.tomcat
 * 作者：   TongHui
 * 创建时间: 2024-08-26 18:52
 * 描述: TODO
 * 版本: 1.0
 */
@Slf4j
public class TomcatManager {
    private static String baseUrl = "http://localhost:";
    private static String username;
    private static String password;
    private static String CONTEXTPATH = "/manager/html/";

    private static TomcatManager tomcatManager = null;

    public TomcatManager(String baseUrl, String username, String password) {

    }


    public synchronized static void getInstance(){
        if (tomcatManager == null){
            synchronized (TomcatManager.class){
                if (tomcatManager == null) {
//                    tomcatManager = new TomcatManager();
                }
            }
        }
    }

    /**
     * 启动项目
     * @param contextPath  上下文路径
     * @return
     * @throws Exception
     */
    public boolean startApplication(String contextPath) throws Exception {
        return executeRequest("start", "?path=" +contextPath);
    }

    /**
     * 停止项目
     * @param contextPath 上下文路径
     * @return
     * @throws Exception
     */
    public boolean stopApplication(String contextPath) throws Exception {
        return executeRequest("stop", "?path=" +contextPath);
    }

    /**
     * 重启项目
     * @param contextPath 上下文路径
     * @return
     * @throws Exception
     */
    public boolean reloadApplication(String contextPath) throws Exception {
        return executeRequest("reload", "?path=" +contextPath);
    }

    /**
     * 卸载项目
     * @param contextPath 上下文路径
     * @return
     * @throws Exception
     */
    public boolean undeployApplication(String contextPath) throws Exception {
        return executeRequest("undeploy", "?path=" +contextPath);
    }

    /**
     * 部署项目
     * @param deployPath     上下文路径
     * @param deployVersion  版本
     * @param deployConfig   xml配置文件路径
     * @param deployWar      war/文件夹路径
     * @return
     * @throws Exception
     */
    public boolean deployApplication(String deployPath,String deployVersion,String deployConfig,String deployWar) throws Exception {
        String contextPath = "?deployPath=" +deployPath;
        if (StrUtil.isNotEmpty(deployVersion)){
            contextPath += "&deployVersion="+deployVersion;
        }
        if (StrUtil.isNotEmpty(deployConfig)){
            contextPath += "&deployConfig="+deployConfig;
        }
        if (StrUtil.isNotEmpty(deployWar)){
            contextPath += "&deployWar="+deployWar;
        }
        return executeRequest("deploy", contextPath);
    }

    private boolean executeRequest(String action, String contextPath) throws Exception {
        String urlString = baseUrl + CONTEXTPATH + action +  contextPath;
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Authorization", "Basic " + encodeCredentials(username, password));
        connection.setDoOutput(true);

        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                String line;
                while ((line = in.readLine()) != null) {
                    log.info(line);
                }
            }
            return true;
        } else {
            log.info("Failed to " + action + " application. HTTP response code: " + responseCode);
            return false;
        }
    }
    private String getNonce() throws Exception{
        URL url = new URL(baseUrl + "/manager/html");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Authorization", "Basic " + encodeCredentials(username, password));

        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        String htmlResponse = response.toString();

        // 解析 HTML 响应以提取 CSRF Nonce
        String nonce = extractNonceFromHtml(htmlResponse);
        return  nonce;
    }


    private String encodeCredentials(String username, String password) {
        String auth = username + ":" + password;
        return Base64.getEncoder().encodeToString(auth.getBytes());
    }
    /**
     * 从 HTML 响应中提取 CSRF Nonce。
     *
     * @param html HTML 响应内容。
     * @return 提取到的 CSRF Nonce 值。
     */
    private String extractNonceFromHtml(String html) {
        // 解析 HTML 内容
        Document document = Jsoup.parse(html);

        // 查找隐藏字段
        Elements inputElements = document.select("input[name=org.apache.catalina.filters.CSRF_NONCE]");
        if (!inputElements.isEmpty()) {
            Element nonceInput = inputElements.first();
            return nonceInput.val(); // 返回值
        } else {
            throw new RuntimeException("CSRF Nonce not found in HTML response");
        }
    }
}
